#include "program_editor.h"
#include "ui_program_editor.h"

ProgramEditor::ProgramEditor(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ProgramEditor)
{
    ui->setupUi(this);

    setupTableWidget();

    cellClicked_row = new int(-1);
    cellClicked_col = new int(-1);
    cellChanged_row = new int(0);
    softKeyboard = new SoftKeyboard();
    ui->ButtoninsertRow->show();
    ui->ButtoninsertRow_1->hide();
    ui->ButtoninsertRow_2->hide();
    ui->frame_2->hide();
    ui->widget_content->hide();
    ui->widget_3->hide();
    lineEditedName = new QString("");
    clickedIoProgram = ui->page_Output_ExtractorOut_1;

    for (int i = 0; i < ui->stackedWidget_col3->count(); i++) {
        QWidget* page = ui->stackedWidget_col3->widget(i);
        QList<QLineEdit*> lineEdits = page->findChildren<QLineEdit*>();
        for (QLineEdit* lineEdit : lineEdits) {
            lineEdit->setPlaceholderText("...");
        }
    }

    bindTextlineWithSoftkeyBoard();
    connectButtonsAndSignals();
}

void ProgramEditor::bindTextlineWithSoftkeyBoard()
{
    ui->lineEdit_2->setFocus();
    ui->lineEdit_2->installEventFilter(this);
    ui->lineEdit_3->setFocus();
    ui->lineEdit_3->installEventFilter(this);
    ui->lineEdit_4->setFocus();
    ui->lineEdit_4->installEventFilter(this);
    ui->lineEdit_5->setFocus();
    ui->lineEdit_5->installEventFilter(this);
    ui->lineEdit_6->setFocus();
    ui->lineEdit_6->installEventFilter(this);
    ui->lineEdit_7->setFocus();
    ui->lineEdit_7->installEventFilter(this);
    ui->lineEdit_8->setFocus();
    ui->lineEdit_8->installEventFilter(this);
    ui->lineEdit_9->setFocus();
    ui->lineEdit_9->installEventFilter(this);
    ui->lineEdit_10->setFocus();
    ui->lineEdit_10->installEventFilter(this);
    ui->lineEdit_11->setFocus();
    ui->lineEdit_11->installEventFilter(this);
}

void ProgramEditor::connectButtonsAndSignals()
{
    connect(ui->ButtonreturnMenu, &QPushButton::clicked, this, &ProgramEditor::pushReturnMenu);

    connect(ui->ButtoninsertRow, &QPushButton::clicked, this, &ProgramEditor::insertRow);
    connect(ui->ButtoninsertRow_1, &QPushButton::clicked, this, &ProgramEditor::insertRowUpperLine);
    connect(ui->ButtoninsertRow_2, &QPushButton::clicked, this, &ProgramEditor::insertRowLowerLine);
    connect(tableWidget, &QTableWidget::cellClicked, [=](int row, int col){
        *cellClicked_row = row;
        *cellClicked_col = col;
    });

    connect(ui->ButtonfindRow, &QPushButton::clicked, this, &ProgramEditor::findSelectedRow);
    connect(ui->pushButton_confirm, &QPushButton::clicked, this, &ProgramEditor::findSelectedButton);
    connect(ui->pushButton_cancel, &QPushButton::clicked, this, &ProgramEditor::findCancelledButton);
    connect(ui->ButtondeleteRow, &QPushButton::clicked, this, &ProgramEditor::deleteSelectedRow);
    connect(tableWidget, &QTableWidget::itemChanged, this, &ProgramEditor::saveTableData);
    connect(this, &ProgramEditor::RowCountChanged, this, &ProgramEditor::saveTableData);

    connect(ui->orderedit, &QPushButton::clicked, this, &ProgramEditor::detectIfCanBeOrderEdited);
    connect(this, &ProgramEditor::OrderEdit, this, &ProgramEditor::doOrderEdit);
    connect(ui->button_hide, &QPushButton::clicked, this, &ProgramEditor::saveOrderEdit);
    connect(ui->button_cancel, &QPushButton::clicked, this, &ProgramEditor::hideOrderEdit);
    connect(ui->compiler, &QPushButton::clicked, this, &ProgramEditor::sendProgramToController);

    connect(ui->toolButton_33, &softkeys::clear_windows, this, [this]() {
        ui->lineEdit_12->setText("");
    });
    connect(ui->toolButton_37, &softkeys::close_windows, this, [this]() {
        ui->widget_3->hide();
        ui->lineEdit_12->setText("");
    });
    connect(ui->toolButton_34, &softkeys::close_windows, this, [this]() {
        ui->widget_3->hide();
        QLineEdit *lineEdit = findChild<QLineEdit*>(*lineEditedName);
        lineEdit->setText(ui->lineEdit_12->text());
        ui->lineEdit_12->setText("");
    });

    // order edit -> C1L*
    connect(ui->col_1_1, &QPushButton::clicked, this, [&](){
        ui->stackedWidget_col2->setCurrentWidget(ui->stackedWidget_col2->findChild<QWidget*>("page_AxisMove"));
        setButtonClickedStyle(ui->widget_col1, ui->col_1_1);

        ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_AxisMove_Move"));
        setButtonClickedStyle(ui->stackedWidget_col2, ui->page_AxisMove_1);
    });
    connect(ui->col_1_2, &QPushButton::clicked, this, [&](){
        ui->stackedWidget_col2->setCurrentWidget(ui->stackedWidget_col2->findChild<QWidget*>("page_Output"));
        setButtonClickedStyle(ui->widget_col1, ui->col_1_2);

        ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_Output_ExtractorOut"));
        setButtonClickedStyle(ui->stackedWidget_col2, ui->page_Output_1);
    });
    connect(ui->col_1_3, &QPushButton::clicked, this, [&](){
        ui->stackedWidget_col2->setCurrentWidget(ui->stackedWidget_col2->findChild<QWidget*>("page_ConditionalWaiting"));
        setButtonClickedStyle(ui->widget_col1, ui->col_1_3);
    });
    connect(ui->col_1_4, &QPushButton::clicked, this, [&](){
        ui->stackedWidget_col2->setCurrentWidget(ui->stackedWidget_col2->findChild<QWidget*>("page_GoTo"));
        setButtonClickedStyle(ui->widget_col1, ui->col_1_4);
    });
    connect(ui->col_1_5, &QPushButton::clicked, this, [&](){
        ui->stackedWidget_col2->setCurrentWidget(ui->stackedWidget_col2->findChild<QWidget*>("page_ConvenienceFunc"));
        setButtonClickedStyle(ui->widget_col1, ui->col_1_5);
    });

    // order edit -> C1L1 -> C2L*
    connect(ui->page_AxisMove_1, &QPushButton::clicked, this, [&](){
        ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_AxisMove_Move"));
        setButtonClickedStyle(ui->stackedWidget_col2, ui->page_AxisMove_1);
    });
    connect(ui->page_AxisMove_2, &QPushButton::clicked, this, [&](){
        ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_AxisMove_Pass"));
        setButtonClickedStyle(ui->stackedWidget_col2, ui->page_AxisMove_2);
    });
    connect(ui->page_AxisMove_3, &QPushButton::clicked, this, [&](){
        ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_AxisMove_ComeBack"));
        setButtonClickedStyle(ui->stackedWidget_col2, ui->page_AxisMove_3);
    });
    connect(ui->page_AxisMove_4, &QPushButton::clicked, this, [&](){
        ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_AxisMove_stop"));
        setButtonClickedStyle(ui->stackedWidget_col2, ui->page_AxisMove_4);
    });
    connect(ui->page_AxisMove_5, &QPushButton::clicked, this, [&](){
        ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_AxisMove_InterpolationMove"));
        setButtonClickedStyle(ui->stackedWidget_col2, ui->page_AxisMove_5);
    });
    connect(ui->page_AxisMove_6, &QPushButton::clicked, this, [&](){
        ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_AxisMove_ContinousInterpolationMove"));
        setButtonClickedStyle(ui->stackedWidget_col2, ui->page_AxisMove_6);
    });
    connect(ui->page_AxisMove_7, &QPushButton::clicked, this, [&](){
        ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_AxisMove_AddDecSpeed"));
        setButtonClickedStyle(ui->stackedWidget_col2, ui->page_AxisMove_7);
    });

    // order edit -> C1L1 -> C2L1 -> C3L*
    connect(ui->page_AxisMove_Move_1, &QPushButton::clicked, this, [&](){
        ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_AxisMove_Move_1_content"));
    });

    // order edit -> C1L2 -> C2L*
    connect(ui->page_Output_1, &QPushButton::clicked, this, [&](){
        ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_Output_ExtractorOut"));
        setButtonClickedStyle(ui->stackedWidget_col2, ui->page_Output_1);
        ui->widget_OnAndOff->hide();
    });
    connect(ui->page_Output_2, &QPushButton::clicked, this, [&](){
        ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_Output_FixtureOutput1"));
        setButtonClickedStyle(ui->stackedWidget_col2, ui->page_Output_2);
    });
    connect(ui->page_Output_3, &QPushButton::clicked, this, [&](){
        ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_Output_FixtureOutput2"));
        setButtonClickedStyle(ui->stackedWidget_col2, ui->page_Output_3);
    });
    connect(ui->page_Output_4, &QPushButton::clicked, this, [&](){
        ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_Output_InjectionMouldOutput"));
        setButtonClickedStyle(ui->stackedWidget_col2, ui->page_Output_4);
    });
    connect(ui->page_Output_5, &QPushButton::clicked, this, [&](){
        ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_Output_PeripheralOutput"));
        setButtonClickedStyle(ui->stackedWidget_col2, ui->page_Output_5);
    });
    connect(ui->page_Output_6, &QPushButton::clicked, this, [&](){
        ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_Output_Option1"));
        setButtonClickedStyle(ui->stackedWidget_col2, ui->page_Output_6);
    });
    connect(ui->page_Output_7, &QPushButton::clicked, this, [&](){
        ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_Output_Option2"));
        setButtonClickedStyle(ui->stackedWidget_col2, ui->page_Output_7);
    });

    // order edit -> C1L2 -> C2L1 -> C3L*
    connect(ui->Button_On, &QPushButton::clicked, this, [&](){
    });
    connect(ui->Button_Off, &QPushButton::clicked, this, [&](){
    });
    connect(ui->Button_And, &QPushButton::clicked, this, [&](){
    });
    connect(ui->page_Output_ExtractorOut_1, &QPushButton::clicked, this, [&](){
        ui->widget_OnAndOff->show();
        clickedIoProgram = ui->page_Output_ExtractorOut_1;
    });
    connect(ui->page_Output_ExtractorOut_2, &QPushButton::clicked, this, [&](){
        ui->widget_OnAndOff->show();
        clickedIoProgram = ui->page_Output_ExtractorOut_2;
    });
    connect(ui->page_Output_ExtractorOut_3, &QPushButton::clicked, this, [&](){
        ui->widget_OnAndOff->show();
        clickedIoProgram = ui->page_Output_ExtractorOut_3;
    });
    connect(ui->page_Output_ExtractorOut_4, &QPushButton::clicked, this, [&](){
        ui->widget_OnAndOff->show();
        clickedIoProgram = ui->page_Output_ExtractorOut_4;
    });
    connect(ui->page_Output_ExtractorOut_5, &QPushButton::clicked, this, [&](){
        ui->widget_OnAndOff->show();
        clickedIoProgram = ui->page_Output_ExtractorOut_5;
    });
    connect(ui->page_Output_ExtractorOut_6, &QPushButton::clicked, this, [&](){
        ui->widget_OnAndOff->show();
        clickedIoProgram = ui->page_Output_ExtractorOut_6;
    });
}

//************  signals slots funcs ************//
void ProgramEditor::sendProgramToController()
{
    emit sendProgramContent(ui->program_name->text());
}

void ProgramEditor::setButtonClickedStyle(QWidget* widget, QPushButton* button)
{
    QList<QPushButton*> buttons = widget->findChildren<QPushButton*>();
    for (QPushButton* btn : buttons) {
        btn->setStyleSheet("");
    }
    button->setStyleSheet("background-color: yellow");
}

void ProgramEditor::saveOrderEdit()
{
    parseFromOrderEdit2Xml();
    parseFromXml2Cell();
    ui->widget_content->hide();
}

void ProgramEditor::hideOrderEdit()
{
    ui->widget_content->hide();
}

void ProgramEditor::detectIfCanBeOrderEdited()
{
    if(*cellClicked_col == 0)
    {
        int currentRow = tableWidget->rowCount();
        if(*cellClicked_row>=0 && *cellClicked_row<=currentRow)
        {
            if(judgeIfCellCanBeEdited("OrderEdit"))
            {
                emit OrderEdit();
            }
        }
    }
}

void ProgramEditor::doOrderEdit()
{
    QString cellData = getTableValue(*cellClicked_row, 0);
    if(cellData != "")
    {
        QFile file(programPath);
        bool if_XMLDoc_local_exist = file.exists();
        XMLDocument XMLDoc_local;
        if (if_XMLDoc_local_exist)
        {
            if(XMLDoc_local.LoadFile(programPath) == tinyxml2::XML_SUCCESS)
            {
                XMLElement* Root = XMLDoc_local.RootElement();
                XMLElement* programElem = Root->FirstChildElement("programName");
                XMLElement* programNameElem = programElem->FirstChildElement(ui->program_name->text().toStdString().c_str());
                if(programNameElem)
                {
                    XMLElement* ele = programNameElem->FirstChildElement((QString("Cell_%1").arg(*cellClicked_row)).toStdString().c_str());
                    if(ele)
                    {
                        QString step_name = ele->Attribute("StepName");
                        ui->widget_content->show();
                        ui->widget_col1->hide();
                        ui->stackedWidget_col2->hide();
                        if(step_name == "直线移动")
                        {
                            ui->stackedWidget_col3->show();
                            ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_AxisMove_Move_1_content"));
                            setOrderEdit_AxisMove_Move_1(&XMLDoc_local, ele);
                        }
                        else if(step_name == "旋转复位" || step_name == "旋转动作"
                                || step_name == "回正"  || step_name == "侧姿"
                                || step_name == "副臂下行"  || step_name == "副臂前进")
                        {
                            ui->stackedWidget_col3->show();
                            ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_Output_ExtractorOut"));
                            if(step_name == "旋转复位")
                                clickedIoProgram = ui->page_Output_ExtractorOut_1;
                            if(step_name == "旋转动作")
                                clickedIoProgram = ui->page_Output_ExtractorOut_2;
                            if(step_name == "回正")
                                clickedIoProgram = ui->page_Output_ExtractorOut_3;
                            if(step_name == "侧姿")
                                clickedIoProgram = ui->page_Output_ExtractorOut_4;
                            if(step_name == "副臂下行")
                                clickedIoProgram = ui->page_Output_ExtractorOut_5;
                            if(step_name == "副臂前进")
                                clickedIoProgram = ui->page_Output_ExtractorOut_6;
                        }
                        else
                        {
                            ui->stackedWidget_col3->hide();
                        }
                    }
                }
            }
        }
    }
    else
    {
        ui->widget_content->show();
        ui->widget_col1->show();
        ui->stackedWidget_col2->show();
        ui->stackedWidget_col3->show();
        ui->stackedWidget_col2->setCurrentWidget(ui->stackedWidget_col2->findChild<QWidget*>("page_AxisMove"));
        ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_AxisMove_Move"));
        ui->col_1_1->setStyleSheet("background-color: yellow");
        ui->page_AxisMove_1->setStyleSheet("background-color: yellow");

        for (int i = 0; i < ui->stackedWidget_col3->count(); i++) {
            QWidget* page = ui->stackedWidget_col3->widget(i);
            QList<QLineEdit*> lineEdits = page->findChildren<QLineEdit*>();
            for (QLineEdit* lineEdit : lineEdits) {
                lineEdit->clear();
            }
        }
    }
}

void ProgramEditor::detectIfRowCntChange()
{
    if((*last_tableRowCount) != (*tableRowCount))
    {
        QTableWidgetItem* newItemInCol0 = tableWidget->item(*tableRowCount - 1,0);
        emit RowCountChanged(newItemInCol0);
        *last_tableRowCount = *tableRowCount;
    }
    return;
}

void ProgramEditor::insertRow()
{
    int currentRow = tableWidget->rowCount();
    if(*cellClicked_row>=0 && *cellClicked_row<=currentRow)
    {
        flipInsertRowButtonDisplay();
    }
    else
    {
        tableWidget->insertRow(currentRow);
    }
}

void ProgramEditor::insertRowUpperLine()
{
    tableWidget->insertRow(*cellClicked_row);
    flipInsertRowButtonDisplay();
    (*tableRowCount)++;
}

void ProgramEditor::insertRowLowerLine()
{
    tableWidget->insertRow(*cellClicked_row+1);
    flipInsertRowButtonDisplay();
    (*tableRowCount)++;
}

void ProgramEditor::deleteSelectedRow()
{
    int selectedRow = tableWidget->currentRow();
    if (selectedRow >= 0) {
        tableWidget->removeRow(selectedRow);
        (*tableRowCount)--;
    }
}

void ProgramEditor::findSelectedRow()
{
    QString buttontext = ui->ButtonfindRow->text();
    if(buttontext == "查找")
    {
        ui->frame_2->show();
        ui->lineEdit->setFocus();
        ui->lineEdit->installEventFilter(this);
    }
    else if(buttontext == "清除查找")
    {
        for(int i=0; i<tableWidget->rowCount(); i++)
        {
            for(int j=0; j<tableWidget->columnCount(); j++)
            {
                QTableWidgetItem* item = tableWidget->item(i, j);
                if (item != nullptr) {
                    item->setBackground(Qt::transparent);
                }
            }
        }
        ui->ButtonfindRow->setText("查找");
    }
}

void ProgramEditor::findSelectedButton()
{
    QString ContentToFind = ui->lineEdit->text();
    if (ContentToFind == "")
    {
        return;
    }
    else
    {
        QList <QTableWidgetItem *> item = tableWidget->findItems(ContentToFind, Qt::MatchContains);
        if(!item.empty())
        {
            ui->ButtonfindRow->setText("清除查找");
            for(int i = 0; i < item.count(); i++)
            {
                item.at(i)->setBackground(Qt::darkGray);
                QTableWidgetItem* item11 = tableWidget->item(item.at(i)->row(), 0);
                tableWidget->scrollToItem(item11);
            }
        }
    }
    ui->frame_2->hide();
    ui->lineEdit->setText("");
}

void ProgramEditor::findCancelledButton()
{
    ui->frame_2->hide();
    ui->lineEdit->setText("");
}

bool ProgramEditor::getChangedCellPos(QTableWidgetItem* item)
{
    *cellChanged_row = item->row();
    if(judgeIfCellCanBeEdited("DirectEdit") == false)
    {
        item->setText("");
        return false;
    }
    return true;
}

bool ProgramEditor::judgeIfCellCanBeEdited(QString EditMode)
{
    int cellToEdit;
    if(EditMode == "DirectEdit")
        cellToEdit = *cellChanged_row;
    else if(EditMode == "OrderEdit")
        cellToEdit = *cellClicked_row;
    else
        return false;

    for(int i=0; i<cellToEdit; i++)
    {
        if(tableWidget->item(i,0))
        {
            if(tableWidget->item(i,0)->text().isEmpty())
                return false;
        }
    }
    return true;
}

void ProgramEditor::saveTableData(QTableWidgetItem* item)
{
    if( !getChangedCellPos(item) )
    {
        return;
    }

    tinyxml2::XMLDocument doc;
    if (doc.LoadFile(docPath) != tinyxml2::XML_SUCCESS) {
        qDebug() << "Error loading XML file when saving edited program";
        return;
    }
    tinyxml2::XMLElement* root = doc.RootElement();
    if (!root) {
        qDebug() << "No root element found in XML file Flexible2ControllerData.xml.";
        return;
    }
    /*
    <root>
    <ProgramElement>
    <ProgramName ProgramName="自动运转程序"
    */
    tinyxml2::XMLElement* programElement = root->FirstChildElement("ProgramElement");
    if (!programElement) {
        qDebug() << "No ProgramElement element found in XML file Flexible2ControllerData.xml.";
        return;
    }
    QString targetProgramName = ui->program_name->text();
    tinyxml2::XMLElement* ProgramName = programElement->FirstChildElement("ProgramName");
    while (ProgramName) {
        const char* programName = ProgramName->Attribute("ProgramName");
        if (programName && std::strcmp(programName, targetProgramName.toStdString().c_str()) == 0) {
            const XMLAttribute* attribute = ProgramName->FirstAttribute();
            while(attribute)
            {
                if(QString(attribute->Name()) == "Cell_0_0")
                    break;
                else
                    attribute = attribute->Next();
            }
            while(attribute)
            {
                //qDebug() << "deleting the attribute " << attribute->Name();
                const char* attributeName = attribute->Name();
                attribute = attribute->Next();
                ProgramName->DeleteAttribute(attributeName);
            }
            for (int row = 0; row < tableWidget->rowCount(); ++row) {
                for (int column = 0; column < tableWidget->columnCount(); ++column) {
                    QString cellData = getTableValue(row, column);
                    QString key = QString("Cell_%1_%2").arg(row).arg(column);
                    ProgramName->SetAttribute(key.toStdString().c_str(),
                                                cellData.toStdString().c_str());
                }
            }
            break;
        }
        ProgramName = ProgramName->NextSiblingElement("ProgramName");
    }
    doc.SaveFile(docPath);
}

//************  auxiliary  funcs ************//
void ProgramEditor::parseAutoProgramFromXml2Cell()
{
    QFile file(programPath);
    bool if_XMLDoc_local_exist = file.exists();
    XMLDocument XMLDoc_local;
    if (if_XMLDoc_local_exist)
    {
        if(XMLDoc_local.LoadFile(programPath) == tinyxml2::XML_SUCCESS)
        {
            XMLElement* Root = XMLDoc_local.RootElement();
            if(Root)
            {
                XMLElement* programElem = Root->FirstChildElement("programName");
                if(programElem)
                {
                    XMLElement* programNameElem = programElem->FirstChildElement(ui->program_name->text().toStdString().c_str());
                    if(programNameElem)
                    {
                        int a = 0;
                        while(programNameElem->FirstChildElement((QString("Cell_%1").arg(a)).toStdString().c_str()))
                        {
                            XMLElement* ele = programNameElem->FirstChildElement((QString("Cell_%1").arg(a)).toStdString().c_str());

                            getCellString_AxisMove_Move_1(ele, a);
                            getCellString_Output_ExtractorOut(ele, a);
                            displayCellString(a);
                            a++;
                        }
                    }
                }
            }
        }
    }
}

void ProgramEditor::parseFromXml2Cell()
{
    QFile file(programPath);
    bool if_XMLDoc_local_exist = file.exists();
    XMLDocument XMLDoc_local;
    if (if_XMLDoc_local_exist)
    {
        if(XMLDoc_local.LoadFile(programPath) == tinyxml2::XML_SUCCESS)
        {
            XMLElement* Root = XMLDoc_local.RootElement();
            if(Root)
            {
                XMLElement* programElem = Root->FirstChildElement("programName");
                if(programElem)
                {
                    XMLElement* programNameElem = programElem->FirstChildElement(ui->program_name->text().toStdString().c_str());
                    if(programNameElem)
                    {
                        XMLElement* ele = programNameElem->FirstChildElement((QString("Cell_%1").arg(*cellClicked_row)).toStdString().c_str());
                        if(ele)
                        {
                            QString pageName = ui->stackedWidget_col3->currentWidget()->objectName();
                            if(pageName == "page_AxisMove_Move_1_content")
                            {
                                getCellString_AxisMove_Move_1(ele, *cellClicked_row);
                            }
                            if(pageName == "page_Output_ExtractorOut")
                            {
                                getCellString_Output_ExtractorOut(ele, *cellClicked_row);
                            }
                        }
                        displayCellString(*cellClicked_row);
                    }
                }
            }
        }
    }
}

void ProgramEditor::displayCellString(int& edited_row)
{
    QString itemEditedText_toAdded = "";
    int queueSize = CellText_queue.size();
    if(queueSize >= 1)
    {
        itemEditedText_toAdded += CellText_queue.dequeue();
    }
    for(int i=0; i<(queueSize-1); i++)
    {
        itemEditedText_toAdded += ",";
        itemEditedText_toAdded += CellText_queue.dequeue();
    }
    tableWidget->setItem(edited_row, 1, new QTableWidgetItem(itemEditedText_toAdded));
    CellText_queue.clear();
}

void ProgramEditor::getCellString_Output_ExtractorOut(XMLElement* ele, int& edited_row)
{
    QString step_name = ele->Attribute("StepName");
    if(step_name != "旋转复位" && step_name != "旋转动作"
             && step_name != "回正"  && step_name != "侧姿回正侧姿副臂下行前进"
             && step_name != "副臂下行"  && step_name != "副臂前进")
        return;
    tableWidget->setItem(edited_row, 0, new QTableWidgetItem(step_name));
}

void ProgramEditor::getCellString_AxisMove_Move_1(XMLElement* ele, int& edited_row)
{
    QString step_name = ele->Attribute("StepName");
    if(step_name != "直线移动")
        return;
    tableWidget->setItem(edited_row, 0, new QTableWidgetItem(step_name));
    XMLElement* ele_axis = ele->FirstChildElement("axis");
    QString axis_name, axis_name_text;
    QString axis_pos;
    QString axis_vel;
    QString CellText;
    while(ele_axis)
    {
        axis_name = ele_axis->Attribute("name");
        axis_pos = ele_axis->FirstChildElement("position")->GetText();
        axis_vel = ele_axis->FirstChildElement("velocity")->GetText();
        if(axis_name == "axis_y")
        {
            axis_name_text = QString("Y轴(");
        }
        if(axis_name == "axis_mx")
        {
            axis_name_text = QString("MX轴(");
        }
        if(axis_name == "axis_mz")
        {
            axis_name_text = QString("MZ轴(");
        }
        if(axis_name == "axis_sx")
        {
            axis_name_text = QString("SX轴(");
        }
        if(axis_name == "axis_sz")
        {
            axis_name_text = QString("SZ轴(");
        }
        CellText = axis_name_text + axis_pos + QString("mm,") + axis_vel + QString("%)");
        CellText_queue.enqueue(CellText);

        ele_axis = ele_axis->NextSiblingElement("axis");
    }
}

void ProgramEditor::parseFromOrderEdit2Xml()
{
    QFile file(programPath);
    XMLDocument XMLDoc_local;
    XMLElement* programNameElem;
    if(!file.exists())
    {
        XMLDeclaration* declaration = XMLDoc_local.NewDeclaration();
        XMLDoc_local.InsertFirstChild(declaration);
        XMLElement* Root = XMLDoc_local.NewElement("root");
        XMLDoc_local.InsertEndChild(Root);
        XMLElement* programElem = XMLDoc_local.NewElement("programName");
        Root->InsertEndChild(programElem);
        XMLElement* programNameElem = XMLDoc_local.NewElement(ui->program_name->text().toStdString().c_str());
        programElem->InsertEndChild(programNameElem);
        for (int row = 0; row < tableWidget->rowCount(); ++row)
        {
            if(tableWidget->item(row, 0))
            {
                if( !(tableWidget->item(row, 0)->text().isEmpty()) )
                {
                    XMLElement* CellElem = XMLDoc_local.NewElement((QString("Cell_%1").arg(row)).toStdString().c_str());
                    CellElem->SetAttribute("StepName", tableWidget->item(row, 0)->text().toStdString().c_str());
                    programNameElem->InsertEndChild(CellElem);
                }
            }
        }
    }
    if(file.exists())
    {
        if(XMLDoc_local.LoadFile(programPath) == tinyxml2::XML_SUCCESS)
        {
            XMLElement* Root = XMLDoc_local.RootElement();
            if(Root)
            {
                XMLElement* programElem = Root->FirstChildElement("programName");
                if(programElem)
                {
                    programNameElem = programElem->FirstChildElement(ui->program_name->text().toStdString().c_str());
                    if(!programNameElem)
                    {
                        programNameElem = XMLDoc_local.NewElement(ui->program_name->text().toStdString().c_str());
                        programElem->InsertEndChild(programNameElem);
                    }
                    if(programNameElem)
                    {
                        XMLElement* ele = programNameElem->FirstChildElement((QString("Cell_%1").arg(*cellClicked_row)).toStdString().c_str());
                        QString pageName = ui->stackedWidget_col3->currentWidget()->objectName();
                        if(ele)
                        {
                            if(ui->stackedWidget_col3->isVisible())
                            {
                                if(pageName == "page_AxisMove_Move_1_content")
                                {
                                    ele->SetAttribute("StepName", "直线移动");
                                    setXml_AxisMove_Move_1(&XMLDoc_local, ele);
                                }
                                if(pageName == "page_Output_ExtractorOut")
                                {
                                    ele->SetAttribute("StepName", (clickedIoProgram->text().split("\n").at(1)).toStdString().c_str());
                                }
                            }
                        }
                        else
                        {
                            XMLElement* new_ele = XMLDoc_local.NewElement((QString("Cell_%1").arg(*cellClicked_row)).toStdString().c_str());
                            XMLElement* pre_ele = programNameElem->FirstChildElement((QString("Cell_%1").arg(*cellClicked_row - 1)).toStdString().c_str());
                            if(pre_ele)
                                programNameElem->InsertAfterChild(pre_ele, new_ele);
                            else
                                programNameElem->InsertFirstChild(new_ele);
                            if(ui->stackedWidget_col3->isVisible())
                            {
                                if(pageName == "page_AxisMove_Move_1_content")
                                {
                                    new_ele->SetAttribute("StepName", "直线移动");
                                    setXml_AxisMove_Move_1(&XMLDoc_local, new_ele);
                                }
                                if(pageName == "page_Output_ExtractorOut")
                                {
                                    new_ele->SetAttribute("StepName", (clickedIoProgram->text().split("\n").at(1)).toStdString().c_str());
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    XMLDoc_local.SaveFile(programPath);
}

void ProgramEditor::setOrderEdit_AxisMove_Move_1(XMLDocument* doc, XMLElement* ele)
{
    setXmlEleOrOrderEdit_AxisMove_Move_1("Xml2OrderEdit", doc, ele, "axis_y", ui->lineEdit_2, ui->lineEdit_10);
    setXmlEleOrOrderEdit_AxisMove_Move_1("Xml2OrderEdit", doc, ele, "axis_mx", ui->lineEdit_3, ui->lineEdit_7);
    setXmlEleOrOrderEdit_AxisMove_Move_1("Xml2OrderEdit", doc, ele, "axis_mz", ui->lineEdit_4, ui->lineEdit_9);
    setXmlEleOrOrderEdit_AxisMove_Move_1("Xml2OrderEdit", doc, ele, "axis_sx", ui->lineEdit_5, ui->lineEdit_11);
    setXmlEleOrOrderEdit_AxisMove_Move_1("Xml2OrderEdit", doc, ele, "axis_sz", ui->lineEdit_6, ui->lineEdit_8);
}

void ProgramEditor::setXml_AxisMove_Move_1(XMLDocument* doc, XMLElement* ele)
{
    setXmlEleOrOrderEdit_AxisMove_Move_1("OrderEdit2Xml", doc, ele, "axis_y", ui->lineEdit_2, ui->lineEdit_10);
    setXmlEleOrOrderEdit_AxisMove_Move_1("OrderEdit2Xml", doc, ele, "axis_mx", ui->lineEdit_3, ui->lineEdit_7);
    setXmlEleOrOrderEdit_AxisMove_Move_1("OrderEdit2Xml", doc, ele, "axis_mz", ui->lineEdit_4, ui->lineEdit_9);
    setXmlEleOrOrderEdit_AxisMove_Move_1("OrderEdit2Xml", doc, ele, "axis_sx", ui->lineEdit_5, ui->lineEdit_11);
    setXmlEleOrOrderEdit_AxisMove_Move_1("OrderEdit2Xml", doc, ele, "axis_sz", ui->lineEdit_6, ui->lineEdit_8);
}

void ProgramEditor::setXmlEleOrOrderEdit_AxisMove_Move_1(const QString& setXmlOrOrderEdit, XMLDocument* doc,
                                                         XMLElement* ele, const QString& axis_name,
                                                         QLineEdit* PosData, QLineEdit* VelData)
{
    if(setXmlOrOrderEdit == "OrderEdit2Xml")
    {
        QString q1 = PosData->text();
        QString q2 = VelData->text();
        if(q1==QString("") || q2==QString(""))
            return;
        XMLElement* axisElem = ele->FirstChildElement("axis");
        XMLElement* posElem;
        XMLElement* velElem;
        while(axisElem)
        {
            if(axisElem->Attribute("name") == axis_name)
            {
                posElem = axisElem->FirstChildElement("position");
                velElem = axisElem->FirstChildElement("velocity");
                break;
            }
            else
                axisElem = axisElem->NextSiblingElement("axis");
        }
        if(!axisElem)
        {
            XMLElement* new_axisElem = doc->NewElement("axis");
            new_axisElem->SetAttribute("name", axis_name.toStdString().c_str());
            ele->InsertEndChild(new_axisElem);
            posElem = doc->NewElement("position");
            new_axisElem->InsertEndChild(posElem);
            velElem = doc->NewElement("velocity");
            new_axisElem->InsertEndChild(velElem);
        }
        posElem->SetText(q1.toStdString().c_str());
        velElem->SetText(q2.toStdString().c_str());
    }
    else if(setXmlOrOrderEdit == "Xml2OrderEdit")
    {
        XMLElement* axisElem = ele->FirstChildElement("axis");
        while(axisElem)
        {
            if(axisElem->Attribute("name") == axis_name)
            {
                QString q1 = axisElem->FirstChildElement("position")->GetText();
                QString q2 = axisElem->FirstChildElement("velocity")->GetText();
                PosData->setText(q1);
                VelData->setText(q2);
                return;
            }
            else
                axisElem = axisElem->NextSiblingElement("axis");
        }
        PosData->setText("");
        VelData->setText("");
    }
}

void ProgramEditor::changeProgramEditAuthority() {
    if(pendantInterfaceData.actionMode == "手动操作")
    {
        ui->ButtondeleteRow->show();
        ui->ButtoninsertRow->show();
    }
    else
    {
        ui->ButtondeleteRow->hide();
        ui->ButtoninsertRow->hide();
    }
}

void ProgramEditor::flipInsertRowButtonDisplay()
{
    if(ui->ButtoninsertRow->isVisible())
    {
        ui->ButtoninsertRow->hide();
        ui->ButtoninsertRow_1->show();
        ui->ButtoninsertRow_2->show();
    }
    else
    {
        ui->ButtoninsertRow->show();
        ui->ButtoninsertRow_1->hide();
        ui->ButtoninsertRow_2->hide();
    }
}

void ProgramEditor::hideInsertRowButtonDisplay()
{
    ui->ButtoninsertRow->show();
    ui->ButtoninsertRow_1->hide();
    ui->ButtoninsertRow_2->hide();
}

void ProgramEditor::setProgramName(const QString &programName)
{
    setupNewTableWidget();
    ui->program_name->setText(programName);
    if(programName == "自动运转程序")
    {
        parseAutoProgramFromXml2Cell();
        saveTableData(tableWidget->item(0,0));
    }
    tinyxml2::XMLDocument doc;
    if (doc.LoadFile(docPath) != tinyxml2::XML_SUCCESS) {
        qDebug() << "Error loading XML file when setting program name";
        return;
    }
    tinyxml2::XMLElement* root = doc.RootElement();
    if (!root) {
        qDebug() << "No root element found in XML file Flexible2ControllerData.xml.";
        return;
    }

    tinyxml2::XMLElement* programElement = root->FirstChildElement("ProgramElement");
    if (!programElement) {
        qDebug() << "No ProgramElement element found in XML file Flexible2ControllerData.xml.";
        return;
    }
    tinyxml2::XMLElement* programName_XML = programElement->FirstChildElement("ProgramName");
    while (programName_XML) {
        const char* elementProgramName = programName_XML->Attribute("ProgramName");
        if (elementProgramName && std::strcmp(elementProgramName,
                                              programName.toStdString().c_str()) == 0) {
            qDebug() << elementProgramName;
            const XMLAttribute* attribute = programName_XML->FirstAttribute();
            while(attribute)
            {
                if(QString(attribute->Name()) == "Cell_0_0")
                    break;
                attribute = attribute->Next();
            }
            while(attribute)
            {
                const char* cellName = attribute->Name();
                int cellrow,cellcol;
                const char* cellData = attribute->Value();
                parseCellValue(cellName, cellrow, cellcol);
                if(cellData)
                {
                    if(cellrow >= tableWidget->rowCount())
                    {
                        tableWidget->insertRow(tableWidget->rowCount());
                    }
                    setTableValue(cellrow, cellcol, QString(cellData));
                }
                attribute = attribute->Next();
            }
            break;
        }
        programName_XML = programName_XML->NextSiblingElement("ProgramName");
    }
    doc.SaveFile(docPath);
    tableWidget->blockSignals(false);
}

bool ProgramEditor::parseCellValue(const char* cellName, int& row, int& col)
{
    int CellChar = 0;
    do
    {
        ++CellChar;
    }while(cellName[CellChar] != '\0' && (!std::isdigit(cellName[CellChar])));
    row = std::atoi(&cellName[CellChar]);
    do
    {
        ++CellChar;
    }while(cellName[CellChar] != '\0' && cellName[CellChar] != '_');
    do
    {
        ++CellChar;
    }while(cellName[CellChar] != '\0' && (!std::isdigit(cellName[CellChar])));
    col = std::atoi(&cellName[CellChar]);
}

void ProgramEditor::setTableValue(int row, int column, const QString &value) {
    if (row >= 0 && row < tableWidget->rowCount() && column >= 0 && column < tableWidget->columnCount()) {
        tableWidget->setItem(row, column, new QTableWidgetItem(value));
    }
}

QString ProgramEditor::getTableValue(int row, int column) {
    if (row >= 0 && row < tableWidget->rowCount() && column >= 0 && column < tableWidget->columnCount()) {
        QTableWidgetItem *item = tableWidget->item(row, column);
        if (item) {
            return item->text();
        }
    }
    return QString();
}

ProgramEditor::~ProgramEditor()
{
    delete ui;
}

void ProgramEditor::setupTableWidget()
{
    tableWidget = new QTableWidget(ui->widget_2);
    tableWidget->setRowCount(7);
    tableWidget->setColumnCount(2);
    tableRowCount = new int(7);
    last_tableRowCount = new int(7);

    tableWidget->setHorizontalHeaderLabels({"指令", "动作处理程序"});
    tableWidget->setColumnWidth(0, 150);
    tableWidget->setColumnWidth(1, 350);

    QHeaderView* verticalHeader = tableWidget->verticalHeader();
    verticalHeader->setFixedWidth(70);
    verticalHeader->setDefaultAlignment(Qt::AlignCenter);

    QVBoxLayout *layout = new QVBoxLayout(ui->widget_2);
    layout->addWidget(tableWidget);
}

void ProgramEditor::setupNewTableWidget()
{
    ui->stackedWidget_col2->setCurrentWidget(ui->stackedWidget_col2->findChild<QWidget*>("page_AxisMove"));
    ui->stackedWidget_col3->setCurrentWidget(ui->stackedWidget_col3->findChild<QWidget*>("page_AxisMove_Move"));
    ui->col_1_1->setStyleSheet("background-color: yellow");
    ui->page_AxisMove_1->setStyleSheet("background-color: yellow");
    tableWidget->blockSignals(true);
    tableWidget->clearContents();
    tableWidget->setRowCount(7);
    for(int i=0; i<7; i++)
    {
        tableWidget->setItem(i, 0, new QTableWidgetItem());
        tableWidget->setItem(i, 1, new QTableWidgetItem());
    }
}

void ProgramEditor::pushReturnMenu()
{
    ui->widget_content->hide();
    emit returnMenu();
}

bool ProgramEditor::eventFilter(QObject *watched, QEvent *event)
{
    if(event->type()==QEvent::MouseButtonRelease)
    {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
        if(mouseEvent->button() == Qt::LeftButton)
        {
            QPoint point = this->pos();

            if(watched == ui->lineEdit)
            {
                softKeyboard->hideInputBufferArea(ui->lineEdit);
                softKeyboard->resize(100,120);
                softKeyboard->move(point+ui->lineEdit->pos());
                softKeyboard->show();
            }
            if(watched == ui->lineEdit_2 || watched == ui->lineEdit_3 || watched == ui->lineEdit_4 ||
                    watched == ui->lineEdit_5 || watched == ui->lineEdit_6 || watched == ui->lineEdit_7 ||
                    watched == ui->lineEdit_8 || watched == ui->lineEdit_9 || watched == ui->lineEdit_10 ||
                    watched == ui->lineEdit_11)
            {
                *lineEditedName = watched->objectName();
                QLineEdit* line_edited = qobject_cast<QLineEdit*>(watched);
                ui->lineEdit_12->setText(line_edited->text());
                ui->widget_3->show();
            }
        }
    }
    return QWidget::eventFilter(watched,event);
}
